home *** CD-ROM | disk | FTP | other *** search
/ World of Education / World of Education.iso / world_p / pcshx10b.zip / PCSHX10B.EXE / GNUFGREP.EXE / GREPDOCS.EXE / MSD_DIR2.C < prev    next >
C/C++ Source or Header  |  1990-08-29  |  5KB  |  238 lines

  1. /*
  2.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  3.  *
  4.  *  A public domain implementation of BSD directory routines for
  5.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  6.  *  August 1897
  7.  */
  8. /*
  9.  *  Slightly hacked by Barry Schwartz, Dec. 1989, and Aug. 1990.
  10.  */
  11.  
  12. #include    <sys/types.h>
  13. #include    <sys/stat.h>
  14. /*#include    <sys/dir.h>        <-- not until later! */
  15. #include    "msd_dir.h"
  16. #include    <malloc.h>
  17. #include    <string.h>
  18. #include    <dos.h>
  19.  
  20. #undef LARGE_DATA
  21. #if defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM)
  22. # define LARGE_DATA
  23. #endif
  24.  
  25. #ifndef    NULL
  26. # define    NULL    0
  27. #endif    /* NULL */
  28.  
  29. #ifndef    MAXPATHLEN
  30. # define    MAXPATHLEN    255
  31. #endif    /* MAXPATHLEN */
  32.  
  33. /* attribute stuff */
  34. #define    A_RONLY        0x01
  35. #define    A_HIDDEN    0x02
  36. #define    A_SYSTEM    0x04
  37. #define    A_LABEL        0x08
  38. #define    A_DIR        0x10
  39. #define    A_ARCHIVE    0x20
  40.  
  41. /* dos call values */
  42. #define    DOSI_FINDF    0x4e
  43. #define    DOSI_FINDN    0x4f
  44. #define    DOSI_SDTA    0x1a
  45.  
  46. #define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  47.  
  48. #if 0
  49.  
  50. #ifndef ATTRIBUTES
  51. /* #define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM) */
  52. #define ATTRIBUTES    (A_RONLY | A_SYSTEM | A_DIR)
  53. #endif
  54.  
  55. #else
  56.  
  57. #define ATTRIBUTES    dos_file_attributes
  58. extern unsigned short ATTRIBUTES;
  59.  
  60. #endif
  61.  
  62. /* what find first/next calls look use */
  63. typedef struct {
  64.     char        d_buf[21];
  65.     char        d_attribute;
  66.     unsigned short    d_time;
  67.     unsigned short    d_date;
  68.     long        d_size;
  69.     char        d_name[13];
  70. } Dta_buf;
  71.  
  72. static    char    *getdirent();
  73. static    void    setdta();
  74. static    void    free_dircontents();
  75.  
  76. static    Dta_buf        dtabuf;
  77. static    Dta_buf        *dtapnt = &dtabuf;
  78. static    union REGS    reg, nreg;
  79.  
  80. #if    defined(LARGE_DATA)
  81. static    struct SREGS    sreg;
  82. #endif
  83.  
  84. DIR    *
  85. opendir(name)
  86.     char    *name;
  87. {
  88.     struct    stat        statb;
  89.     DIR            *dirp;
  90.     char            c;
  91.     char            *s;
  92.     struct _dircontents    *dp;
  93.     char            nbuf[MAXPATHLEN + 1];
  94.     
  95.     if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  96.         return (DIR *) NULL;
  97.     if (Newisnull(dirp, DIR))
  98.         return (DIR *) NULL;
  99.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  100.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  101.     else
  102.         (void) strcat(strcpy(nbuf, name), "*.*");
  103.     dirp->dd_loc = 0;
  104.     setdta();
  105.     dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  106.     if ((s = getdirent(nbuf)) == (char *) NULL)
  107.         return dirp;
  108.     do {
  109.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  110.             malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  111.         {
  112.             if (dp)
  113.                 free((char *) dp);
  114.             free_dircontents(dirp->dd_contents);
  115.             return (DIR *) NULL;
  116.         }
  117.         if (dirp->dd_contents)
  118.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  119.         else
  120.             dirp->dd_contents = dirp->dd_cp = dp;
  121.         (void) strcpy(dp->_d_entry, s);
  122.         dp->_d_next = (struct _dircontents *) NULL;
  123.     } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  124.     dirp->dd_cp = dirp->dd_contents;
  125.  
  126.     return dirp;
  127. }
  128.  
  129. void
  130. closedir(dirp)
  131.     DIR    *dirp;
  132. {
  133.     free_dircontents(dirp->dd_contents);
  134.     free((char *) dirp);
  135. }
  136.  
  137. struct direct    *
  138. readdir(dirp)
  139.     DIR    *dirp;
  140. {
  141.     static    struct direct    dp;
  142.     
  143.     if (dirp->dd_cp == (struct _dircontents *) NULL)
  144.         return (struct direct *) NULL;
  145.     dp.d_namlen = dp.d_reclen =
  146.         strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  147.     strlwr(dp.d_name);        /* JF */
  148.     dp.d_ino = 0;
  149.     dirp->dd_cp = dirp->dd_cp->_d_next;
  150.     dirp->dd_loc++;
  151.  
  152.     return &dp;
  153. }
  154.  
  155. void
  156. seekdir(dirp, off)
  157.     DIR    *dirp;
  158.     long    off;
  159. {
  160.     long            i = off;
  161.     struct _dircontents    *dp;
  162.  
  163.     if (off < 0)
  164.         return;
  165.     for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  166.         ;
  167.     dirp->dd_loc = off - (i + 1);
  168.     dirp->dd_cp = dp;
  169. }
  170.  
  171. long
  172. telldir(dirp)
  173.     DIR    *dirp;
  174. {
  175.     return dirp->dd_loc;
  176. }
  177.  
  178. static    void
  179. free_dircontents(dp)
  180.     struct    _dircontents    *dp;
  181. {
  182.     struct _dircontents    *odp;
  183.  
  184.     while (dp) {
  185.         if (dp->_d_entry)
  186.             free(dp->_d_entry);
  187.         dp = (odp = dp)->_d_next;
  188.         free((char *) odp);
  189.     }
  190. }
  191.  
  192. static    char    *
  193. getdirent(dir)
  194.     char    *dir;
  195. {
  196.     if (dir != (char *) NULL) {        /* get first entry */
  197.         reg.h.ah = DOSI_FINDF;
  198.         reg.h.cl = ATTRIBUTES;
  199. #if    defined(LARGE_DATA)
  200.         reg.x.dx = FP_OFF(dir);
  201.         sreg.ds = FP_SEG(dir);
  202. #else
  203.         reg.x.dx = (unsigned) dir;
  204. #endif
  205.     } else {                /* get next entry */
  206.         reg.h.ah = DOSI_FINDN;
  207. #if    defined(LARGE_DATA)
  208.         reg.x.dx = FP_OFF(dtapnt);
  209.         sreg.ds = FP_SEG(dtapnt);
  210. #else
  211.         reg.x.dx = (unsigned) dtapnt;
  212. #endif
  213.     }
  214. #if    defined(LARGE_DATA)
  215.     intdosx(®, &nreg, &sreg);
  216. #else
  217.     intdos(®, &nreg);
  218. #endif
  219.     if (nreg.x.cflag)
  220.         return (char *) NULL;
  221.  
  222.     return dtabuf.d_name;
  223. }
  224.  
  225. static    void
  226. setdta()
  227. {
  228.     reg.h.ah = DOSI_SDTA;
  229. #if    defined(LARGE_DATA)
  230.     reg.x.dx = FP_OFF(dtapnt);
  231.     sreg.ds = FP_SEG(dtapnt);
  232.     intdosx(®, &nreg, &sreg);
  233. #else
  234.     reg.x.dx = (int) dtapnt;
  235.     intdos(®, &nreg);
  236. #endif
  237. }
  238.